home *** CD-ROM | disk | FTP | other *** search
- Subject: v19i082: Cnews production release, Part05/19
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: utzoo!henry
- Posting-number: Volume 19, Issue 82
- Archive-name: cnews2/part05
-
- : ---CUT HERE---
- echo 'batch/sendbatches':
- sed 's/^X//' >'batch/sendbatches' <<'!'
- X#! /bin/sh
- X# Master batching control.
- X
- X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
- X. ${NEWSCONFIG-/usr/lib/news/bin/config}
- X
- XPATH=$NEWSCTL/bin:$NEWSBIN/batch:$NEWSBIN:$NEWSPATH ; export PATH
- Xumask $NEWSUMASK
- X
- Xorigpath="$PATH"
- X
- Xparms=$NEWSCTL/batchparms
- Xlog=$NEWSCTL/batchlog # also same with suffixes .o and .oo
- X
- X# lock against multiple simultaneous execution
- Xlock="$NEWSCTL/LOCKbatch"
- Xltemp="$NEWSCTL/L.$$"
- Xecho $$ >$ltemp
- Xtrap "rm -f $ltemp ; exit 0" 0 1 2 15
- Xif newslock $ltemp $lock
- Xthen
- X trap "rm -f $ltemp $lock ; exit 0" 0 1 2 15
- Xelse
- X exit 0
- Xfi
- X
- Xcd $NEWSARTS/out.going
- X
- X# Determine what systems are being requested, in what order.
- Xcase "$1"
- Xin
- X -d)
- X debug=yes
- X shift
- X ;;
- Xesac
- Xcase $#
- Xin
- X 0)
- X if egrep '^/default/[ ]' $parms >/dev/null # default line found
- X then
- X syses=`ls -tr | egrep -v '^[@.]'` # oldest first
- X else
- X syses="`egrep '^[^/#]' $parms | awk '{ print $1 }'`"
- X fi
- X ;;
- X
- X *)
- X syses="$*"
- X ;;
- Xesac
- Xcase $debug
- Xin
- X yes)
- X for sys in $syses
- X do
- X echo $sys
- X done
- X exit 0
- X ;;
- Xesac
- X
- X# Start up logging.
- Xmv $log.o $log.oo
- Xmv $log $log.o
- Xdate >$log
- X
- X# Run through them.
- Xfor sys in $syses
- Xdo
- X # Move into his directory, include it in search path.
- X here=$NEWSARTS/out.going/$sys
- X if test ! -d $here
- X then
- X echo "$0: cannot find batch directory for \`$sys'" >>$log
- X continue
- X fi
- X cd $here
- X PATH=$here:$origpath ; export PATH
- X NEWSSITE=$sys ; export NEWSSITE # For site-specific programs.
- X
- X # Is there anything to do?
- X files=`echo togo*`
- X if test "$files" = 'togo*' || test "$files" = "togo" -a ! -s togo
- X then
- X continue # no
- X fi
- X
- X # Pick up the batchparms line.
- X ctlline="`egrep \"^$sys[ ]\" $parms | sed 1q`"
- X if test " $ctlline" = " "
- X then
- X ctlline="`egrep '^/default/[ ]' $parms | sed 1q`"
- X fi
- X set $ctlline
- X if test " $#" -ne 6
- X then
- X echo "$0: bad or missing batchparms line for \`$sys'" >>$log
- X continue
- X fi
- X batchsize=$2
- X limit=$3
- X batcher=$4
- X muncher=$5
- X sender=$6
- X
- X # How many to send?
- X outstand=`queuelen $sys`
- X nbatch=`expr $limit - $outstand`
- X roomfor=`spacefor $batchsize outbound $sys`
- X if test " $nbatch" -gt " $roomfor"
- X then
- X nbatch=$roomfor
- X fi
- X
- X # If not allowed to send, remember reason.
- X status='batches flowing'
- X if test " $nbatch" -le 0
- X then
- X if test " $roomfor" -le 0
- X then
- X status='disk too full for batching'
- X else
- X status='queue full, no recent movement'
- X fi
- X fi
- X
- X # Try sending some.
- X while test " $nbatch" -gt 0
- X do
- X # Does he have batches prepared already?
- X if test "`echo togo.[0-9]`" = 'togo.[0-9]'
- X then
- X # No -- need some more batches.
- X if test ! -s togo && test ! -s togo.next
- X then
- X break # Nothing left to do.
- X fi
- X batchsplit $batchsize
- X fi
- X
- X # Send some batches.
- X them=`ls | egrep '^togo\.[0-9]' | sed "${nbatch}q"`
- X for f in $them
- X do
- X if $batcher -d $NEWSARTS $f | $muncher | $sender $sys
- X then
- X rm $f
- X else
- X echo "$0: batching for \`$sys' failed" >>$log
- X exit 1
- X fi
- X done
- X ndone=`echo $them | wc -w`
- X nbatch=`expr $nbatch - $ndone`
- X
- X # Recheck the space -- it can fall for other reasons.
- X roomfor=`spacefor $batchsize outbound $sys`
- X if test " $nbatch" -gt " $roomfor"
- X then
- X nbatch=$roomfor
- X fi
- X done
- X
- X # Report status, if appropriate.
- X nart=`cat togo* | wc -l | awk '{print $1}'`
- X if test " $nart" -gt 0
- X then
- X echo "$sys backlog $nart ($status)" >>$log
- X fi
- Xdone
- !
- echo 'batch/batchih':
- sed 's/^X//' >'batch/batchih' <<'!'
- X#! /bin/sh
- X# ihave batch preparer
- X
- X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
- X. ${NEWSCONFIG-/usr/lib/news/bin/config}
- X
- XPATH=$NEWSCTL/bin:$NEWSBIN/batch:$NEWSBIN:$NEWSPATH ; export PATH
- Xumask $NEWSUMASK
- X
- Xcase "$1"
- Xin
- X -d)
- X shift ; shift # ignore -d option
- X ;;
- Xesac
- X
- Xdest=`expr "$NEWSSITE" : "^\([^.]*\)\.ihave$"`
- Xcase "$dest"
- Xin
- X '')
- X dest="$NEWSSITE"
- X ;;
- Xesac
- Xme="`newshostname`"
- X
- Xecho "Newsgroups: to.$dest"
- Xecho "Subject: ihave $me"
- Xecho "Control: ihave $me"
- Xecho
- Xexec cat $*
- !
- echo 'batch/compcun':
- sed 's/^X//' >'batch/compcun' <<'!'
- X#! /bin/sh
- X# Invoke compress, adding silly 2.11-compatible header.
- X# 12-bit compression is the lowest common denominator among news sites,
- X# and is often almost as good as the much-more-costly 16-bit compression.
- X
- Xecho "#! cunbatch"
- Xcompress -b 12
- Xstatus=$?
- Xcase "$status"
- Xin
- X 2)
- X status=0 # compress stupidity
- X ;;
- Xesac
- Xexit $status
- !
- echo 'batch/batcher.c':
- sed 's/^X//' >'batch/batcher.c' <<'!'
- X/*
- X * batcher - send a bunch of news articles as an unbatch script
- X *
- X * Usage: batcher [-d dir] listfile
- X *
- X * where listfile is a file containing a list, one per line, of
- X * full pathnames of files containing articles. Only the first
- X * field of each line is looked at, so there can be more if needed
- X * for other things.
- X *
- X * The -d option specifies a directory where most articles are
- X * likely to be; the program chdirs there to speed things up.
- X */
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <signal.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "fgetmfs.h"
- X
- X#ifndef READSIZE
- X#define READSIZE 8192 /* allows for even 4.2 worst case file systems */
- X#endif
- Xchar buffer[READSIZE];
- X
- Xchar *progname;
- X
- Xchar *dir = NULL; /* NULL means don't bother chdiring. */
- Xint dirlen; /* strlen(dir) */
- Xint debug = 0; /* Debugging? */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int c;
- X int errflg = 0;
- X extern int optind;
- X extern char *optarg;
- X register FILE *list;
- X char *article;
- X int ret;
- X
- X progname = argv[0];
- X while ((c = getopt(argc, argv, "d:x")) != EOF)
- X switch (c) {
- X case 'd': /* Directory containing many articles. */
- X dir = optarg;
- X dirlen = strlen(dir);
- X break;
- X case 'x': /* Debugging. */
- X debug++;
- X break;
- X case '?':
- X default:
- X errflg++;
- X break;
- X }
- X if (errflg || optind != argc-1) {
- X (void) fprintf(stderr,
- X "Usage: batcher [-d dir] listfile\n");
- X exit(2);
- X }
- X
- X list = fopen(argv[optind], "r");
- X if (list == NULL)
- X error("unable to open `%s'", argv[optind]);
- X
- X if (dir != NULL)
- X if (chdir(dir) < 0)
- X error("can't chdir to `%s'", dir);
- X
- X while ((article = fgetms(list)) != NULL) {
- X process(article);
- X free(article);
- X }
- X if (!feof(list))
- X error("fgetmfs failure", "");
- X
- X exit(0);
- X}
- X
- X/*
- X - process - process an article
- X */
- Xprocess(article)
- Xchar *article;
- X{
- X char *p;
- X register int artfile;
- X register int count;
- X struct stat sbuf;
- X
- X *(article + strcspn(article, "\n\t ")) = '\0';
- X if (dir != NULL && strncmp(article, dir, dirlen) == 0 &&
- X article[dirlen] == '/')
- X p = article+dirlen+1;
- X else
- X p = article;
- X
- X artfile = open(p, 0);
- X if (artfile < 0) {
- X /*
- X * Can't read the article. This isn't necessarily a
- X * disaster, since things like cancellations will do
- X * this. Mumble and carry on.
- X */
- X if (debug)
- X warning("can't find `%s'", p);
- X return;
- X }
- X
- X if (fstat(artfile, &sbuf) < 0)
- X error("internal disaster, can't fstat", "");
- X if ((sbuf.st_mode&S_IFMT) != S_IFREG) {
- X close(artfile);
- X return; /* Don't try to batch directories etc. */
- X }
- X
- X (void) printf("#! rnews %ld\n", sbuf.st_size);
- X fflush(stdout);
- X
- X while ((count = read(artfile, buffer, sizeof buffer)) > 0)
- X if (write(1, buffer, count) != count)
- X error("write failure in `%s'", article);
- X if (count < 0)
- X error("read failure in `%s'", article);
- X
- X (void) close(artfile);
- X}
- !
- echo 'batch/c7encode.c':
- sed 's/^X//' >'batch/c7encode.c' <<'!'
- X#include <stdio.h>
- X
- X#ifdef SCCSID
- Xstatic char *SccsId = "@(#)encode.c 1.3 5/15/85";
- X#endif /* SCCSID */
- X
- X/*
- X * Produce a 7 bit printable encoding of stdin on stdout.
- X *
- X * Encoding uses acsii chars from ' ' .. 'z'
- X * (040 .. 0172) (0x20 - 0x7a) inclusive
- X *
- X * Method is to expand 3 chars -> 4 6 bit ones.
- X * Then collect 13 6 bit chars, and spread the 13th over
- X * the preceding 12, so that each of the 12 chars is now
- X * 6.5 bits. These 2 6.5 bit chars are a little hard
- X * to represent on most common machines (one of these days
- X * sane hosts will have 1/2 bits just for this program)
- X * so we take a pair of them, and represent that in 13 bits.
- X * 13 bits (max value 8191) can be represented as
- X * A * 91 + B
- X * where A < 91, B < 91 (91^2 == 8281, so it fits!)
- X *
- X * Each of A and B is encoded as a character by adding 32
- X * to make it printable (ie: 0x20).
- X *
- X * The termination conditions are foul beyond belief. Don't
- X * monkey with them!
- X *
- X * If you think its a fluke that 040 .. 0171 just happen to
- X * be the chars that Piet Beertema's uucp 'f' protocol transmits
- X * as single bytes, you're insane. 0172 chars are produced
- X * with lower frequency than any other (given random data)
- X * so the doubling that occurs with that we will just suffer.
- X * (A newer 'f' proto, sometime, will probably not use 0172)
- X */
- X
- X/*
- X * the following pair of characters cannot legally occur
- X * in normal output (since 90*91 + 90 == 8280, which > 2^13)
- X * so we use them to indicate that the data that follows is the
- X * terminator. The character immediately following this
- X * pair is the length of the (expanded) terminator (which
- X * otherwise might be indeterminable)
- X */
- X#define ENDMARK1 ((90*91 + 90) / 91 + ' ')
- X#define ENDMARK2 ((90*91 + 90) % 91 + ' ')
- X
- Xmain()
- X{
- X register char *p;
- X register char *e;
- X register c;
- X char b3[3];
- X
- X p = b3;
- X e = b3 + 3;
- X while ((c = getchar()) != EOF) {
- X *p++ = c;
- X if (p == e) {
- X encode(b3, 3);
- X p = b3;
- X }
- X }
- X encode(b3, p - b3);
- X flushout();
- X exit(0);
- X}
- X
- Xstatic char b13[13];
- Xstatic int cnt = 0;
- X
- Xencode(c, n)
- X register char *c;
- X int n;
- X{
- X register char *p;
- X register i = cnt;
- X register j;
- X char b4[4];
- X
- X p = b4;
- X
- X p[0] = (c[0] >> 2) & 0x3f;
- X p[1] = ((c[0] & 0x3) << 4) | ((c[1] >> 4) & 0xf);
- X p[2] = ((c[1] & 0xF) << 2) | ((c[2] >> 6) & 0x3);
- X if (n == 3)
- X p[3] = c[2] & 0x3f;
- X else
- X p[3] = n;
- X
- X c = &b13[i];
- X for (j = 4; --j >= 0; i++) {
- X if (i == 13) {
- X dumpcode(b13, 13);
- X c = b13;
- X i = 0;
- X }
- X *c++ = *p++;
- X }
- X cnt = i;
- X}
- X
- Xflushout()
- X{
- X putchar(ENDMARK1);
- X putchar(ENDMARK2);
- X putchar(cnt + ' ');
- X dumpcode(b13, cnt);
- X}
- X
- Xdumpcode(p, n)
- X register char *p;
- X register int n;
- X{
- X register last;
- X register c;
- X
- X if (n == 13)
- X n--, last = p[12];
- X else if (n & 1)
- X last = (1 << (6-1));
- X else
- X last = 0;
- X
- X for ( ; n > 0; n -= 2) {
- X c = *p++ << 6;
- X c |= *p++;
- X if (last & (1 << (6-1)))
- X c |= (1 << 12);
- X last <<= 1;
- X
- X /*
- X * note: 91^2 > 2^13, 90^2 < 2^13, (91 + ' ') is printable
- X */
- X
- X /* oh for a compiler that would only do one division... */
- X putchar((c / 91) + ' ');
- X putchar((c % 91) + ' ');
- X }
- X}
- !
- echo 'batch/coder.h':
- sed 's/^X//' >'batch/coder.h' <<'!'
- Xchar header[] = "Decode the following with bdecode\n";
- Xchar codeset[] =
- X "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
- X
- X#define ENCODE(c) codeset[c]
- X
- Xextern short crctab[];
- X#define CRC(crc, c) crc = (crc >> 8) ^ crctab[(crc^c) & 0xff]
- !
- echo 'batch/viamail':
- sed 's/^X//' >'batch/viamail' <<'!'
- X#! /bin/sh
- X# send via mail, unprotected (typically used for bencode output only)
- X
- X( echo ; cat ) | mail $1!rnews
- !
- echo 'batch/viainews':
- sed 's/^X//' >'batch/viainews' <<'!'
- X#! /bin/sh
- X# Feed batch to inews, for ihave/sendme mostly.
- X
- Xexec inews -h -W
- !
- echo 'batch/nocomp':
- sed 's/^X//' >'batch/nocomp' <<'!'
- X#! /bin/sh
- X# Null muncher, for uncompressed links.
- X
- Xexec cat $*
- !
- echo 'batch/bencode.c':
- sed 's/^X//' >'batch/bencode.c' <<'!'
- X/*
- X * bencode [file]
- X */
- X#include <stdio.h>
- X#include "coder.h"
- X#define MAXPERLINE 78 /* max chars/line */
- Xchar *myname;
- X
- Xmain(argc,argv)
- X char **argv;
- X{
- X register FILE *fin = stdin, *fout = stdout; /* faster in a register */
- X register int c, bcount, ccount = MAXPERLINE-1;
- X register long word, nbytes;
- X register int crc;
- X
- X myname = argv[0];
- X if (sizeof(word) < 4)
- X fprintf(stderr, "%s: word size too small\n", myname), exit(1);
- X if (argc == 2 && (fin = fopen(argv[1], "r")) == NULL) {
- X fprintf(stderr, "%s: ", myname);
- X perror(argv[1]);
- X exit(1);
- X }
- X else if (argc > 2) {
- X fprintf(stderr, "Usage: %s [file]\n", myname);
- X exit(1);
- X }
- X
- X#define PUTC(c) \
- X putc(c, fout); \
- X if (--ccount == 0) { \
- X putc('\n', fout); \
- X ccount = MAXPERLINE-1; \
- X }
- X
- X fputs(header, fout);
- X word = 0;
- X bcount = 3;
- X crc = 0;
- X for (nbytes = 0; (c = getc(fin)) != EOF; nbytes++) {
- X CRC(crc, c);
- X word <<= 8;
- X word |= c;
- X if (--bcount == 0) {
- X PUTC(ENCODE((word >> 18) & 077));
- X PUTC(ENCODE((word >> 12) & 077));
- X PUTC(ENCODE((word >> 6) & 077));
- X PUTC(ENCODE((word ) & 077));
- X word = 0;
- X bcount = 3;
- X }
- X }
- X /*
- X * A trailing / marks end of data.
- X * The last partial encoded word follows in hex,
- X * preceded by a byte count.
- X */
- X if (ccount != MAXPERLINE-1) /* avoid empty lines */
- X putc('\n', fout);
- X fprintf(fout, "/%d%x\n", 3-bcount, word);
- X /*
- X * And finally the byte count and CRC.
- X */
- X fprintf(fout, "%ld %x\n", nbytes, crc & 0xffff);
- X exit(0);
- X}
- !
- echo 'batch/crctab.c':
- sed 's/^X//' >'batch/crctab.c' <<'!'
- X/* generated using the CRC-16 polynomial x^16 + x^15 + x^2 + 1 = 0120001 */
- Xshort crctab[256] = {
- X 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
- X 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
- X 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
- X 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
- X 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
- X 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
- X 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
- X 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
- X 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
- X 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
- X 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
- X 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
- X 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
- X 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
- X 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
- X 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
- X 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
- X 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
- X 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
- X 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
- X 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
- X 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
- X 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
- X 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
- X 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
- X 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
- X 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
- X 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
- X 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
- X 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
- X 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
- X 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
- X};
- !
- echo 'batch/compb':
- sed 's/^X//' >'batch/compb' <<'!'
- X#! /bin/sh
- X# like comp except use bencode
- X
- X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
- X. ${NEWSCONFIG-/usr/lib/news/bin/config}
- X
- XPATH=$NEWSCTL/bin:$NEWSBIN/batch:$NEWSBIN:$NEWSPATH ; export PATH
- Xumask $NEWSUMASK
- X
- Xcompress -b 12 | bencode
- Xexit 0 # compress exit status sometimes stupid
- !
- echo 'batch/viapmail':
- sed 's/^X//' >'batch/viapmail' <<'!'
- X#! /bin/sh
- X# send via mail (protected against stupid mailers)
- X
- X( echo ; sed 's/^/N/' ) | mail $1!rnews
- !
- echo 'contrib/putenv.alt.c':
- sed 's/^X//' >'contrib/putenv.alt.c' <<'!'
- X/*
- X * From: chip@ateng.ateng.com (Chip Salzenberg)
- X * Newsgroups: comp.unix.wizards
- X * Subject: Re: replacement for putenv()
- X * Date: 13 Feb 89 16:51:05 GMT
- X *
- X * Here is a rather nice replacement for putenv(). I wrote it for the BSD port
- X * of my deliver program. (I know it's source, but it's short.) Its nicest
- X * feature is the avoidance of memory waste when it is called several times.
- X */
- X
- Xint
- Xputenv(s)
- Xchar *s;
- X{
- X static char **env_array;
- X static int env_size;
- X char *e;
- X int i, j;
- X
- X if (env_array == NULL) {
- X for (i = 0; environ[i]; ++i)
- X ;
- X env_size = i + 10; /* arbitrary */
- X env_array = (char **) malloc(env_size * sizeof(char *));
- X if (env_array == NULL)
- X return 1;
- X memcpy((char *)env_array, (char *)environ,
- X (int) ((i + 1) * sizeof(char *)));
- X environ = env_array;
- X } else if (environ != env_array)
- X fprintf(stderr, "putenv: warning: someone moved environ!\n");
- X
- X if ((e = strchr(s, '=')) != NULL)
- X ++e;
- X else
- X e = s + strlen(s);
- X
- X j = 0;
- X for (i = 0; env_array[i]; ++i)
- X if (strncmp(env_array[i], s, e - s) != 0)
- X env_array[j++] = env_array[i];
- X
- X if (j + 1 >= env_size) {
- X env_size += 10; /* arbitrary */
- X env_array = (char **) realloc((char *)env_array,
- X env_size * sizeof(char **));
- X if (env_array == NULL)
- X return 1;
- X }
- X
- X env_array[j++] = s;
- X env_array[j] = NULL;
- X
- X environ = env_array;
- X return 0;
- X}
- !
- echo 'contrib/dbz':
- sed 's/^X//' >'contrib/dbz' <<'!'
- XFrom utgpu!jarvis.csri.toronto.edu!mailrus!sharkey!b-tech!zeeff Tue Feb 7 17:19:31 EST 1989
- XArticle: 1900 of news.software.b:
- XPath: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!sharkey!b-tech!zeeff
- XFrom: zeeff@b-tech.ann-arbor.mi.us (Jon Zeeff)
- XNewsgroups: news.software.b
- XSubject: Re: Dbz and news 2.11
- XMessage-ID: <5095@b-tech.ann-arbor.mi.us>
- XDate: 4 Feb 89 18:56:09 GMT
- XReferences: <20@bungia.Bungia.MN.ORG>
- XReply-To: zeeff@b-tech.ann-arbor.mi.us (Jon Zeeff)
- XDistribution: usa
- XOrganization: Branch Technology Ann Arbor, MI
- XLines: 322
- X
- XIn article <20@bungia.Bungia.MN.ORG> ahby@bungia.MN.ORG (Shane P. McCarron) writes:
- X>Some time ago the dbz sources were posted for use with news 2.11.
- X>Patches have been posted, and a number of sites are using these
- X>routines to make news run faster on machines without dbm libraries. I
- X>seem to remember some controversy surrounding the use of these
- X>routines. Something about their containing AT&T proprietary stuff? I
- X>realize that by asking this I am going to get a hundred answers, all
- X>of them different. What I am really looking for is ONE AUTHORITATIVE
- X>ANSWER. Can anyone out there say for sure whether this code is freely
- X>distributable or not?
- X
- XAs the author, I suppose I can supply an authorative answer. Dbz
- Xcontains no AT&T code at all. The only thing in it not written by me
- Xis the hashing, and that is taken from pathalias (with permission).
- X
- XHere it is if anyone missed it:
- X
- X
- X/*
- Xdbz.c V1.5
- X
- XCopyright 1988 Jon Zeeff (umix!b-tech!zeeff)
- XYou can use this code in any manner, as long as you leave my name on it
- Xand don't hold me responsible for any problems with it.
- X
- XHacked on by gdb@ninja.UUCP (David Butler); Sun Jun 5 00:27:08 CDT 1988
- X
- XThese routines replace dbm as used by the usenet news software
- X(it's not a full dbm replacement by any means). It's fast and
- Xsimple. It contains no AT&T code.
- X
- XBSD sites will notice some savings in disk space. Sys V sites without
- Xdbm will notice much faster operation.
- X
- XNote: .pag files created by version 1.[0-3] need to be recreated before
- X using this version.
- X
- XThis code relies on the fact that news stores a pointer to the history
- Xfile as the dbm data. It doesn't store another copy of the key like
- Xdbm does so it saves disk space. All you can do is fetch() and
- Xstore() data.
- X
- XJust make news with the DBM option and link with dbz.o.
- X*/
- X
- X/*
- X Set this to the something several times larger than the maximum # of
- X lines in a history file. It should be a prime number.
- X*/
- X#define INDEX_SIZE 99991L
- X
- X#define DEBUG if (0) printf /* for no debugging */
- X/* #define DEBUG if (1) printf /* for debugging */
- X/* #define DEBUG if (debug) printf /* for "rn" type debugging */
- X
- X/* Note: let the optimizer remove any if(0) or if(1) code above */
- X
- X#include <fcntl.h>
- X#include <string.h>
- X#include <ctype.h>
- X
- Xlong lseek();
- X
- Xstatic long get_ptr();
- Xstatic int put_ptr();
- Xstatic void lcase();
- Xstatic long hash();
- Xstatic void crcinit();
- X
- Xtypedef struct {
- X char *dptr;
- X int dsize;
- X} datum;
- X
- Xstatic int Data_fd; /* points to /usr/lib/news/[n]history */
- Xstatic int Index_fd = -1; /* points to /usr/lib/news/[n]history.pag */
- X
- Xint
- Xdbminit(name)
- Xchar *name;
- X{
- X char index_file[1024]; /* index file name */
- X void crcinit();
- X
- X if (Index_fd >= 0) {
- X DEBUG("dbminit: dbminit aready called once\n");
- X return(-1); /* init already called once */
- X }
- X
- X strcpy(index_file, name);
- X strcat(index_file, ".pag");
- X
- X /* if we don't have permission to open the pag file for read/write */
- X /* then we may never attempt a store(). If we do, it will fail */
- X
- X if ((Index_fd = open(index_file, O_RDWR)) < 0 &&
- X (Index_fd = open(index_file, O_RDONLY)) < 0 &&
- X (Index_fd = open(index_file, O_CREAT | O_RDWR, 0644)) < 0)
- X {
- X DEBUG("dbminit: Index_file open failed\n");
- X return(-1);
- X }
- X
- X if ((Data_fd = open(name, O_RDONLY)) < 0) {
- X
- X /* The only time the data file does not exist is when */
- X /* expire is running (as "news") and it is ok to create it */
- X /* If we don't have "permission" the create will fail, too */
- X
- X if (close(creat(name, 0644)) < 0 ||
- X (Data_fd = open(name, O_RDONLY)) < 0) {
- X DEBUG("dbminit: Data_file open failed\n");
- X close(Index_fd);
- X Index_fd = -1;
- X return(-1);
- X }
- X }
- X
- X crcinit(); /* initialize the crc table */
- X DEBUG("dbminit: succeeded\n");
- X return(0);
- X}
- X
- Xint
- Xdbmclose()
- X{
- X if (Index_fd >= 0) {
- X close(Index_fd);
- X Index_fd = -1;
- X close(Data_fd);
- X }
- X DEBUG("dbmclose: succeeded\n");
- X return(0);
- X}
- X
- X/* get an entry from the database */
- Xdatum
- Xfetch(key)
- Xdatum key;
- X{
- X long index_ptr;
- X long index_size = INDEX_SIZE;
- X char buffer[1024];
- X static long data_ptr;
- X datum output;
- X long hash();
- X long get_ptr();
- X void lcase();
- X
- X DEBUG("fetch: (%s)\n", key.dptr);
- X
- X for (index_ptr = hash(key.dptr, key.dsize);
- X --index_size && (data_ptr = get_ptr(index_ptr)) >= 0L;
- X index_ptr = ++index_ptr % INDEX_SIZE) {
- X
- X lseek(Data_fd, data_ptr, 0);
- X read(Data_fd, buffer, (unsigned)key.dsize);
- X
- X /* key should be article id and no tab */
- X
- X /* lcase(buffer, key.dsize); lcase is a B news botch */
- X if (buffer[key.dsize - 1] == '\t') {
- X buffer[key.dsize - 1] = '\0';
- X }
- X
- X DEBUG("fetch: buffer (%s)\n", buffer);
- X if (strncmp(key.dptr, buffer, key.dsize) == 0) {
- X /* we found it */
- X output.dptr = (char *)&data_ptr;
- X output.dsize = sizeof(long);
- X DEBUG("fetch: successful\n");
- X return(output);
- X }
- X }
- X
- X /* we didn't find it */
- X
- X output.dptr = (char *)0;
- X output.dsize = 0;
- X DEBUG("fetch: failed\n");
- X return(output);
- X}
- X
- X/* add an entry to the database */
- Xstore(key, data)
- Xdatum key;
- Xdatum data;
- X{
- X /* lint complains about a possible pointer alignment problem here */
- X /* it is not a problem because dptr is the first element of a */
- X /* structure and should be aligned for anything */
- X DEBUG("store: (%s, %ld)\n", key.dptr, *((long *)data.dptr));
- X return(put_ptr(hash(key.dptr, key.dsize), *((long *)data.dptr)));
- X}
- X
- X/* get a data file pointer from the specified location in the index file */
- X
- Xstatic long
- Xget_ptr(index_ptr)
- Xlong index_ptr;
- X{
- X long data_ptr;
- X
- X DEBUG("get_ptr: (%ld)\n", index_ptr);
- X
- X /* seek to where it should be */
- X lseek(Index_fd, (long)(index_ptr * sizeof(long)) ,0);
- X
- X /* read it */
- X if (read(Index_fd, (char *)&data_ptr, sizeof(long)) != sizeof(long) ||
- X data_ptr == 0L) {
- X DEBUG("get_ptr: failed\n");
- X return(-1L);
- X }
- X DEBUG("get_ptr: succeeded\n");
- X return(--data_ptr); /* remove the offset we added in put_ptr */
- X}
- X
- X/* put a data file pointer into the specified location in the index file */
- X/* move down further if slots are full (linear probing) */
- Xstatic
- Xput_ptr(index_ptr, data_ptr)
- Xlong index_ptr;
- Xlong data_ptr;
- X{
- X long get_ptr();
- X long index_size = INDEX_SIZE;
- X
- X /* find an empty slot */
- X while (--index_size && get_ptr(index_ptr) >= 0L) {
- X index_ptr = ++index_ptr % INDEX_SIZE;
- X }
- X
- X if (index_size == 0L) {
- X DEBUG("put_ptr: hash table overflow - failed\n");
- X return(-1);
- X }
- X
- X /* seek to spot */
- X lseek(Index_fd, (long)(index_ptr * sizeof(long)), 0);
- X
- X ++data_ptr; /* add one so that we can use 0 as no pointer */
- X
- X /* write in data */
- X if (write(Index_fd, (char *)&data_ptr, sizeof(long)) != sizeof(long)) {
- X DEBUG("put_ptr: write failed\n");
- X return(-1);
- X }
- X
- X DEBUG("put_ptr: succeeded\n");
- X return(0);
- X}
- X
- Xstatic void
- Xlcase(s, n)
- Xregister char *s;
- Xregister int n;
- X{
- X for (; n > 0; --n, ++s) {
- X *s = tolower(*s);
- X }
- X}
- X
- X/* This is a simplified version of the pathalias hashing function.
- X * Thanks to Steve Belovin and Peter Honeyman
- X *
- X * hash a string into a long int. 31 bit crc (from andrew appel).
- X * the crc table is computed at run time by crcinit() -- we could
- X * precompute, but it takes 1 clock tick on a 750.
- X *
- X * This fast table calculation works only if POLY is a prime polynomial
- X * in the field of integers modulo 2. Since the coefficients of a
- X * 32-bit polynomial won't fit in a 32-bit word, the high-order bit is
- X * implicit. IT MUST ALSO BE THE CASE that the coefficients of orders
- X * 31 down to 25 are zero. Happily, we have candidates, from
- X * E. J. Watson, "Primitive Polynomials (Mod 2)", Math. Comp. 16 (1962):
- X * x^32 + x^7 + x^5 + x^3 + x^2 + x^1 + x^0
- X * x^31 + x^3 + x^0
- X *
- X * We reverse the bits to get:
- X * 111101010000000000000000000000001 but drop the last 1
- X * f 5 0 0 0 0 0 0
- X * 010010000000000000000000000000001 ditto, for 31-bit crc
- X * 4 8 0 0 0 0 0 0
- X */
- X
- X#define POLY 0x48000000L /* 31-bit polynomial (avoids sign problems) */
- X
- Xstatic long CrcTable[128];
- X
- Xstatic void
- Xcrcinit()
- X{ register int i, j;
- X register long sum;
- X
- X for (i = 0; i < 128; ++i) {
- X sum = 0L;
- X for (j = 7 - 1; j >= 0; --j)
- X if (i & (1 << j))
- X sum ^= POLY >> j;
- X CrcTable[i] = sum;
- X }
- X DEBUG("crcinit: done\n");
- X}
- X
- Xstatic long
- Xhash(name, size)
- Xregister char *name;
- Xregister int size;
- X{
- X register long sum = 0L;
- X
- X while (size--) {
- X sum = (sum >> 7) ^ CrcTable[(sum ^ (*name++)) & 0x7f];
- X }
- X DEBUG("hash: returns (%ld)\n", sum % INDEX_SIZE);
- X return(sum % INDEX_SIZE);
- X}
- X
- X--
- X Jon Zeeff zeeff@b-tech.ann-arbor.mi.us
- X Ann Arbor, MI mailrus!b-tech!zeeff
- X
- X
- !
- echo 'contrib/dirfns':
- sed 's/^X//' >'contrib/dirfns' <<'!'
- Xecho 'directory.3':
- Xsed 's/^X//' >'directory.3' <<'!'
- XX.TH DIRECTORY 3 imported
- XX.DA 9 Oct 1985
- XX.SH NAME
- XXopendir, readdir, telldir, seekdir, rewinddir, closedir \- high-level directory operations
- XX.SH SYNOPSIS
- XX.B #include <sys/types.h>
- XX.br
- XX.B #include <ndir.h>
- XX.PP
- XX.SM
- XX.B DIR
- XX.B *opendir(filename)
- XX.br
- XX.B char *filename;
- XX.PP
- XX.SM
- XX.B struct direct
- XX.B *readdir(dirp)
- XX.br
- XX.B DIR *dirp;
- XX.PP
- XX.SM
- XX.B long
- XX.B telldir(dirp)
- XX.br
- XX.B DIR *dirp;
- XX.PP
- XX.SM
- XX.B seekdir(dirp, loc)
- XX.br
- XX.B DIR *dirp;
- XX.br
- XX.B long loc;
- XX.PP
- XX.SM
- XX.B rewinddir(dirp)
- XX.br
- XX.B DIR *dirp;
- XX.PP
- XX.SM
- XX.B closedir(dirp)
- XX.br
- XX.B DIR *dirp;
- XX.SH DESCRIPTION
- XXThis library provides high-level primitives for directory scanning,
- XXsimilar to those available for 4.2BSD's (very different) directory system.
- XX.\"The purpose of this library is to simulate
- XX.\"the new flexible length directory names of 4.2bsd UNIX
- XX.\"on top of the old directory structure of v7.
- XXIt incidentally provides easy portability to and from 4.2BSD (insofar
- XXas such portability is not compromised by other 4.2/VAX dependencies).
- XX.\"It allows programs to be converted immediately
- XX.\"to the new directory access interface,
- XX.\"so that they need only be relinked
- XX.\"when moved to 4.2bsd.
- XX.\"It is obtained with the loader option
- XX.\".BR \-lndir .
- XX.PP
- XX.I Opendir
- XXopens the directory named by
- XX.I filename
- XXand associates a
- XX.I directory stream
- XXwith it.
- XX.I Opendir
- XXreturns a pointer to be used to identify the
- XX.I directory stream
- XXin subsequent operations.
- XXThe pointer
- XX.SM
- XX.B NULL
- XXis returned if
- XX.I filename
- XXcannot be accessed or is not a directory.
- XX.PP
- XX.I Readdir
- XXreturns a pointer to the next directory entry.
- XXIt returns
- XX.B NULL
- XXupon reaching the end of the directory or detecting
- XXan invalid
- XX.I seekdir
- XXoperation.
- XX.PP
- XX.I Telldir
- XXreturns the current location associated with the named
- XX.I directory stream.
- XX.PP
- XX.I Seekdir
- XXsets the position of the next
- XX.I readdir
- XXoperation on the
- XX.I directory stream.
- XXThe new position reverts to the one associated with the
- XX.I directory stream
- XXwhen the
- XX.I telldir
- XXoperation was performed.
- XXValues returned by
- XX.I telldir
- XXare good only for the lifetime of the DIR pointer from
- XXwhich they are derived.
- XXIf the directory is closed and then reopened,
- XXthe
- XX.I telldir
- XXvalue may be invalidated
- XXdue to undetected directory compaction in 4.2BSD.
- XXIt is safe to use a previous
- XX.I telldir
- XXvalue immediately after a call to
- XX.I opendir
- XXand before any calls to
- XX.I readdir.
- XX.PP
- XX.I Rewinddir
- XXresets the position of the named
- XX.I directory stream
- XXto the beginning of the directory.
- XX.PP
- XX.I Closedir
- XXcauses the named
- XX.I directory stream
- XXto be closed,
- XXand the structure associated with the DIR pointer to be freed.
- XX.PP
- XXA
- XX.I direct
- XXstructure is as follows:
- XX.PP
- XX.RS
- XX.nf
- XXstruct direct {
- XX /* unsigned */ long d_ino; /* inode number of entry */
- XX unsigned short d_reclen; /* length of this record */
- XX unsigned short d_namlen; /* length of string in d_name */
- XX char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
- XX};
- XX.fi
- XX.RE
- XX.PP
- XXThe
- XX.I d_reclen
- XXfield is meaningless in non-4.2BSD systems and should be ignored.
- XXThe use of a
- XX.I long
- XXfor
- XX.I d_ino
- XXis also a 4.2BSDism;
- XX.I ino_t
- XX(see
- XX.IR types (5))
- XXshould be used elsewhere.
- XXThe macro
- XX.I DIRSIZ(dp)
- XXgives the minimum memory size needed to hold the
- XX.I direct
- XXvalue pointed to by
- XX.IR dp ,
- XXwith the minimum necessary allocation for
- XX.IR d_name .
- XX.PP
- XXThe preferred way to search the current directory for entry ``name'' is:
- XX.PP
- XX.RS
- XX.nf
- XX len = strlen(name);
- XX dirp = opendir(".");
- XX if (dirp == NULL) {
- XX fprintf(stderr, "%s: can't read directory .\\n", argv[0]);
- XX return NOT_FOUND;
- XX }
- XX while ((dp = readdir(dirp)) != NULL)
- XX if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) {
- XX closedir(dirp);
- XX return FOUND;
- XX }
- XX closedir(dirp);
- XX return NOT_FOUND;
- XX.RE
- XX.\".SH LINKING
- XX.\"This library is accessed by specifying ``-lndir'' as the
- XX.\"last argument to the compile line, e.g.:
- XX.\".PP
- XX.\" cc -I/usr/include/ndir -o prog prog.c -lndir
- XX.SH "SEE ALSO"
- XXopen(2),
- XXclose(2),
- XXread(2),
- XXlseek(2)
- XX.SH HISTORY
- XXWritten by
- XXKirk McKusick at Berkeley (ucbvax!mckusick).
- XXMiscellaneous bug fixes from elsewhere.
- XXThe size of the data structure has been decreased to avoid excessive
- XXspace waste under V7 (where filenames are 14 characters at most).
- XXFor obscure historical reasons, the include file is also available
- XXas
- XX.IR <ndir/sys/dir.h> .
- XXThe Berkeley version lived in a separate library (\fI\-lndir\fR),
- XXwhereas ours is
- XXpart of the C library, although the separate library is retained to
- XXmaximize compatibility.
- XX.PP
- XXThis manual page has been substantially rewritten to be informative in
- XXthe absence of a 4.2BSD manual.
- XX.SH BUGS
- XXThe
- XX.I DIRSIZ
- XXmacro actually wastes a bit of space due to some padding requirements
- XXthat are an artifact of 4.2BSD.
- XX.PP
- XXThe returned value of
- XX.I readdir
- XXpoints to a static area that will be overwritten by subsequent calls.
- XX.PP
- XXThere are some unfortunate name conflicts with the \fIreal\fR V7
- XXdirectory structure definitions.
- X!
- Xecho 'dir.h':
- Xsed 's/^X//' >'dir.h' <<'!'
- XX/* dir.h 4.4 82/07/25 */
- XX
- XX/*
- XX * A directory consists of some number of blocks of DIRBLKSIZ
- XX * bytes, where DIRBLKSIZ is chosen such that it can be transferred
- XX * to disk in a single atomic operation (e.g. 512 bytes on most machines).
- XX *
- XX * Each DIRBLKSIZ byte block contains some number of directory entry
- XX * structures, which are of variable length. Each directory entry has
- XX * a struct direct at the front of it, containing its inode number,
- XX * the length of the entry, and the length of the name contained in
- XX * the entry. These are followed by the name padded to a 4 byte boundary
- XX * with null bytes. All names are guaranteed null terminated.
- XX * The maximum length of a name in a directory is MAXNAMLEN.
- XX *
- XX * The macro DIRSIZ(dp) gives the amount of space required to represent
- XX * a directory entry. Free space in a directory is represented by
- XX * entries which have dp->d_reclen >= DIRSIZ(dp). All DIRBLKSIZ bytes
- XX * in a directory block are claimed by the directory entries. This
- XX * usually results in the last entry in a directory having a large
- XX * dp->d_reclen. When entries are deleted from a directory, the
- XX * space is returned to the previous entry in the same directory
- XX * block by increasing its dp->d_reclen. If the first entry of
- XX * a directory block is free, then its dp->d_ino is set to 0.
- XX * Entries other than the first in a directory do not normally have
- XX * dp->d_ino set to 0.
- XX */
- XX#define DIRBLKSIZ 512
- XX#ifdef VMUNIX
- XX#define MAXNAMLEN 255
- XX#else
- XX#define MAXNAMLEN 14
- XX#endif
- XX
- XXstruct direct {
- XX /* unsigned */ long d_ino; /* inode number of entry */
- XX unsigned short d_reclen; /* length of this record */
- XX unsigned short d_namlen; /* length of string in d_name */
- XX char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
- XX};
- XX
- XX/*
- XX * The DIRSIZ macro gives the minimum record length which will hold
- XX * the directory entry. This requires the amount of space in struct direct
- XX * without the d_name field, plus enough space for the name with a terminating
- XX * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
- XX */
- XX#undef DIRSIZ
- XX#define DIRSIZ(dp) \
- XX ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
- XX
- XX#ifndef KERNEL
- XX/*
- XX * Definitions for library routines operating on directories.
- XX */
- XXtypedef struct _dirdesc {
- XX int dd_fd;
- XX long dd_loc;
- XX long dd_size;
- XX char dd_buf[DIRBLKSIZ];
- XX} DIR;
- XX#ifndef NULL
- XX#define NULL 0
- XX#endif
- XXextern DIR *opendir();
- XXextern struct direct *readdir();
- XXextern long telldir();
- XX#ifdef void
- XXextern void seekdir();
- XXextern void closedir();
- XX#endif
- XX#define rewinddir(dirp) seekdir((dirp), (long)0)
- XX#endif KERNEL
- X!
- Xecho 'makefile':
- Xsed 's/^X//' >'makefile' <<'!'
- XXDIR = closedir.o opendir.o readdir.o seekdir.o telldir.o
- XXCFLAGS=-O -I. -Dvoid=int
- XXDEST=..
- XX
- XXall: $(DIR)
- XX
- XXmv: $(DIR)
- XX mv $(DIR) $(DEST)
- XX
- XXcpif: dir.h
- XX cp dir.h /usr/include/ndir.h
- XX
- XXclean:
- XX rm -f *.o
- X!
- Xecho 'closedir.c':
- Xsed 's/^X//' >'closedir.c' <<'!'
- XXstatic char sccsid[] = "@(#)closedir.c 4.2 3/10/82";
- XX
- XX#include <sys/types.h>
- XX#include <dir.h>
- XX
- XX/*
- XX * close a directory.
- XX */
- XXvoid
- XXclosedir(dirp)
- XX register DIR *dirp;
- XX{
- XX close(dirp->dd_fd);
- XX dirp->dd_fd = -1;
- XX dirp->dd_loc = 0;
- XX free((char *)dirp);
- XX}
- X!
- Xecho 'opendir.c':
- Xsed 's/^X//' >'opendir.c' <<'!'
- XX/* Copyright (c) 1982 Regents of the University of California */
- XX
- XXstatic char sccsid[] = "@(#)opendir.c 4.4 11/12/82";
- XX
- XX#include <sys/types.h>
- XX#include <sys/stat.h>
- XX#include <dir.h>
- XX
- XX/*
- XX * open a directory.
- XX */
- XXDIR *
- XXopendir(name)
- XX char *name;
- XX{
- XX register DIR *dirp;
- XX register int fd;
- XX struct stat statbuf;
- XX char *malloc();
- XX
- XX if ((fd = open(name, 0)) == -1)
- XX return NULL;
- XX if (fstat(fd, &statbuf) == -1 || !(statbuf.st_mode & S_IFDIR)) {
- XX close(fd);
- XX return NULL;
- XX }
- XX if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
- XX close (fd);
- XX return NULL;
- XX }
- XX dirp->dd_fd = fd;
- XX dirp->dd_loc = 0;
- XX dirp->dd_size = 0; /* so that telldir will work before readdir */
- XX return dirp;
- XX}
- X!
- Xecho 'readdir.c':
- Xsed 's/^X//' >'readdir.c' <<'!'
- XX/* Copyright (c) 1982 Regents of the University of California */
- XX
- XXstatic char sccsid[] = "@(#)readdir.c 4.3 8/8/82";
- XX
- XX#include <sys/types.h>
- XX#include <dir.h>
- XX
- XX/*
- XX * read an old stlye directory entry and present it as a new one
- XX */
- XX#define ODIRSIZ 14
- XX
- XXstruct olddirect {
- XX ino_t od_ino;
- XX char od_name[ODIRSIZ];
- XX};
- XX
- XX/*
- XX * get next entry in a directory.
- XX */
- XXstruct direct *
- XXreaddir(dirp)
- XX register DIR *dirp;
- XX{
- XX register struct olddirect *dp;
- XX static struct direct dir;
- XX
- XX for (;;) {
- XX if (dirp->dd_loc == 0) {
- XX dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
- XX DIRBLKSIZ);
- XX if (dirp->dd_size <= 0) {
- XX dirp->dd_size = 0;
- XX return NULL;
- XX }
- XX }
- XX if (dirp->dd_loc >= dirp->dd_size) {
- XX dirp->dd_loc = 0;
- XX continue;
- XX }
- XX dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
- XX dirp->dd_loc += sizeof(struct olddirect);
- XX if (dp->od_ino == 0)
- XX continue;
- XX dir.d_ino = dp->od_ino;
- XX strncpy(dir.d_name, dp->od_name, ODIRSIZ);
- XX dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
- XX dir.d_namlen = strlen(dir.d_name);
- XX dir.d_reclen = DIRBLKSIZ;
- XX return (&dir);
- XX }
- XX}
- X!
- Xecho 'seekdir.c':
- Xsed 's/^X//' >'seekdir.c' <<'!'
- XXstatic char sccsid[] = "@(#)seekdir.c 4.9 3/25/83";
- XX
- XX#include <sys/param.h>
- XX#include <dir.h>
- XX
- XX/*
- XX * seek to an entry in a directory.
- XX * Only values returned by "telldir" should be passed to seekdir.
- XX */
- XXvoid
- XXseekdir(dirp, loc)
- XX register DIR *dirp;
- XX long loc;
- XX{
- XX long curloc, base, offset;
- XX struct direct *dp;
- XX extern long lseek();
- XX
- XX curloc = telldir(dirp);
- XX if (loc == curloc)
- XX return;
- XX base = loc & ~(DIRBLKSIZ - 1);
- XX offset = loc & (DIRBLKSIZ - 1);
- XX (void) lseek(dirp->dd_fd, base, 0);
- XX dirp->dd_size = 0;
- XX dirp->dd_loc = 0;
- XX while (dirp->dd_loc < offset) {
- XX dp = readdir(dirp);
- XX if (dp == NULL)
- XX return;
- XX }
- XX}
- X!
- Xecho 'telldir.c':
- Xsed 's/^X//' >'telldir.c' <<'!'
- XXstatic char sccsid[] = "@(#)telldir.c 4.1 2/21/82";
- XX
- XX#include <sys/types.h>
- XX#include <dir.h>
- XX
- XX/*
- XX * return a pointer into a directory
- XX */
- XXlong
- XXtelldir(dirp)
- XX DIR *dirp;
- XX{
- XX long lseek();
- XX
- XX return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc);
- XX}
- X!
- Xecho done
- !
- echo 'contrib/README':
- sed 's/^X//' >'contrib/README' <<'!'
- XThis directory contains some software from others that might be of use
- Xin getting C News running in an unusual environment.
- X
- XWE MAKE ABSOLUTELY NO GUARANTEES ABOUT QUALITY OR USABILITY. EVERYTHING
- XHERE IS SUPPLIED "AS IS". SOMETIMES WE HAVEN'T EVEN TESTED IT.
- !
- echo 'contrib/nntpmail/README':
- sed 's/^X//' >'contrib/nntpmail/README' <<'!'
- XThis directory contains.
- X
- Xmailing_lists support for moderating, redistributing and
- X gatewaying mailing lists into newsgroups/vice-versa.
- Xmail_to_group support for being able to "mail comp.unix.wizards"
- Xnntp_support support for posting articles remotely using
- X NNTP.
- Xpost_via_mail support for posting articles remotely by mailing
- X them there. Poor man's NNTP.
- !
- echo 'contrib/nntpmail/post_via_mail/README':
- sed 's/^X//' >'contrib/nntpmail/post_via_mail/README' <<'!'
- XThis directory contains C news support for posting news to a remote
- Xserver by mailing the article to a special alias.
- X
- Xfrontend_inews parse options, masquerades news headers so they can
- X go through mail, mail the article to the remote
- X alias. Install as $NEWSLIB/inews
- X
- Xserver_inews The special alias on the news server should invke this
- X e.g.
- X feednews: "|/usr/lib/newsbin/server_inews"
- X
- X Make sure the nntp server invokes server_inews and
- X not fake_inews (instant infinite loop!).
- X
- X You can find this file in ../nntp_support
- X
- Xusenet a version of ../mail_to_newsgroup/usenet that works
- X by remailing the article.
- !
- echo 'contrib/nntpmail/post_via_mail/frontend_inews':
- sed 's/^X//' >'contrib/nntpmail/post_via_mail/frontend_inews' <<'!'
- X#! /bin/sh
- X# inews [-p] [-d k] [-x site] [-hMD] [-t subj] [-n ng] [-e exp] [-F ref] \
- X# [-d dist] [-a mod] [-f from] [-o org] [-C ng] [file...] - inject news:
- X#
- X# pseudo inews that supports the use of a central posting server accessed
- X# via mail. This provides less opportunities to inject fake messages, and
- X# relies on mail to do fancy things like hiding names of workstations and
- X# providing full-name return addresses.
- X#
- X# Jean-Francois Lamy (lamy@ai.toronto.edu) 88-02-11
- X
- X#NEWSCTL=${NEWSCTL-/usr/lib/news}
- X#NEWSBIN=${NEWSBIN-/usr/lib/newsbin}
- X#NEWSARTS=${NEWSARTS-/usr/spool/news}
- XNEWSCTL=/local/share/news
- XNEWSBIN=/local/lib/news
- XNEWSARTS=/var/spool/news
- XPATH=$NEWSBIN:$NEWSCTL:$NEWSBIN/relay:/bin:/usr/bin:/usr/ucb; export PATH
- X
- Xallowed=sandra\|rayan\|lamy # tailor: local news admin (may be "")
- Xhdrspresent=no
- X
- Xwhoami=/tmp/in$$who # just created to determine effective uid
- Xinput=/tmp/in$$in # uncensored input
- Xcensart=/tmp/in$$cens # censored input
- Xrmlist="$input $censart"
- Xegrep=egrep
- X
- X# figure out where the remote server is. We mail even if we are on the
- X# server, in order to garantee proper return addresses
- X servaddr=feednews@news-server.csri.toronto.edu
- X
- Xumask 2
- Xtrap '' 1 2 15 # ignore signals to avoid losing articles
- X
- X# "inews -p": invoke rnews
- Xcase "$1" in
- X-p)
- X shift
- X exec rnews $* # rnews, bailing out at or near line 1
- X ;;
- Xesac
- X
- X# parse arguments for options, cat headers onto $input; cat files onto $input
- X>$input
- Xwhile :
- Xdo
- X case $# in
- X 0) break ;; # arguments exhausted
- X esac
- X
- X case "$1" in
- X -debug) shift; debug="$1" ;; # peculiar to C news
- X -x) shift; exclusion="-x $1" ;; # you're welcome, erik (2.11)
- X -h) hdrspresent=yes ;;
- X -M) # TODO: what's this *really* do? dunno, find out
- X ;;
- X -D) # obsolete, undocumented: meant "don't check for recordings".
- X # last present in B 2.10.1, invoked by readnews for followups.
- X ;;
- X -t) shift; echo "Subject: $1" >>$input ;;
- X -n) shift; echo "Newsgroups: $1" >>$input ;;
- X -e) shift; echo "Expires: $1" >>$input ;;
- X -F) # undocumented in B 2.10.1, documented in B 2.11.
- X shift; echo "References: $1" >>$input ;;
- X -d) shift; echo "Distribution: $1" >>$input ;;
- X -a) shift; echo "Approved: $1" >>$input ;;
- X
- X # pass next options as environment variables to client.censor
- X
- X -f) shift; PASSEDFROM="$1" ;; # complex due to Sender:
- X -o) shift; ORGANIZATION="$1"; export ORGANIZATION ;;
- X
- X -[cC])
- X # megakludge-o-rama
- X # first, permit only to super-users
- X >$whoami
- X whoever = "`ls -l $whoami | awk '{print $3}'`"
- X case $whoever in
- X root|$allowed) : a winner ;;
- X *)
- X echo "$0: $1 restricted to super-users " >&2
- X exit 1
- X ;;
- X esac
- X rm -f $whoami
- X case "$1" in
- X -C) cat <<! >>$input # generate -C header
- XNewsgroups: $ng
- XSubject: newgroup $2
- XControl: newgroup $2
- XApproved: $whoever@`hostname`.`domainname`
- X
- Xcreated by inews -C
- X!
- X shift
- X ;;
- X -c) cat <<! >>$input # generate -c header
- XNewsgroups: $ng
- XSubject: $2
- XControl: $2
- XApproved: $whoever@`hostname`.`domainname`
- X
- Xcreated by inews -c.
- X!
- X shift
- X ;;
- X esac
- X ;;
- X -*)
- X echo "$0: bad option $1" >&2
- X exit 1
- X ;;
- X *)
- X case "$hdrspresent" in
- X no) echo "" >>$input; hdrspresent=yes ;;
- X esac
- X cat "$1" >>$input # is a filename; append file
- X fileseen=yes
- X ;;
- X esac
- X shift # pass option or filename (any value was done above)
- Xdone
- X
- X# if no files named, read stdin
- Xcase "$fileseen" in
- Xyes) ;;
- X*)
- X case "$hdrspresent" in
- X no) echo "" >>$input; hdrspresent=yes ;;
- X esac
- X # capture incoming news in case inews fails
- X if cat >>$input; then
- X : far out
- X else
- X echo "$0: lost news; cat returned status $?" >&2
- X exit 1
- X fi
- X ;;
- Xesac
- X
- X(
- X# trivial censoring, before passing on to mailer.
- XORGANIZATION=${ORGANIZATION=`cat ${NEWSCTL}/organi?ation`}
- Xawk "BEGIN { subject = 0; body = 0; skipping = 0 ;
- X newsgroups = 0; distribution = 0; organization = 0;
- X print \"To: $servaddr\" }
- Xbody == 1 { print; next }
- X/[A-Za-z-]*:[ ]*$/ { next }
- X/^$|^[ ][ \t]*$/ { if (!body) {
- X if (!organization)
- X print \"Organization: $ORGANIZATION\";
- X if (!newsgroups) print \"Newsgroups: $groups\";
- X if (!subject) print \"Subject: (none)\";
- X }
- X print; body = 1; next
- X }
- X/^Organization:/ { organization = 1; skipping = 0; print; next }
- X/^Newsgroups:/ { newsgroups = 1; skipping = 0; print; next }
- X/^Distribution:/ { distribution = 1; skipping = 0; print; next }
- X/^Subject:/ { subject = 1; skipping = 0; print; next }
- X/^To:|^Cc:|^X-To:/ { skipping = 1; next }
- X/^From |^Return-Path:/ { skipping = 1; next }
- X/^Apparently-To:/ { skipping = 1; next }
- X/^[ ]/ { if (skipping) next }
- X { print }
- X" <$input >$censart
- Xif test -r $HOME/.signature; then
- X echo "-- " >>$censart
- X sed 5q $HOME/.signature >>$censart # glue on first bit of signature
- Xfi
- X
- Xif /usr/lib/sendmail -t ${PASSEDFROM+-f"$PASSEDFROM"} <$censart
- Xthen
- X rm -f $rmlist # far out, it worked
- X exit 0
- Xelse
- X status=$?
- X echo\
- X"$0: could not send article to server; sendmail returned status $status" >&2
- X echo "$0: processed news article can be found in $input" >&2
- X exit $status
- Xfi
- X) &
- !
- echo 'contrib/nntpmail/post_via_mail/usenet':
- sed 's/^X//' >'contrib/nntpmail/post_via_mail/usenet' <<'!'
- X#!/bin/sh
- X#
- X# post.news
- X#
- X# meant to be invoked as a sendmail-compatible mailer from zmailer. Arguments
- X# are the newsgroups to which the article should be posted. A complete
- X# message, including To:, From: and From_ line expected on stdin.
- X#
- X# To use this script as a transport agent, add the following to scheduler.cntl:
- X# usenet/* 1m 10 0 0 root daemon sm -c $channel news
- X# The definition of the news transport agent in sm.cf should contain
- X# news m /usr/lib/zmail/post.news post.news $u
- X# (adjust this to reflect the actual location of the installed copy of this
- X# script, of course)
- X#
- X# Jean-Francois Lamy (lamy@ai.toronto.edu), 88-02-13
- X# based on code by Rayan Zachariassen.
- X
- X# Notes:
- X# - The news program invoked by this script should trust From: lines
- X# (otherwise workstation name hiding, full-name id generation and
- X# all other smarts done by router.cf will be lost)
- X# - router.cf checks local parts with embedded dots for membership in the
- X# active newsgroups file and routes them through this transport agent. One
- X# word newsgroup names are not tested in that fashion, because of the risk
- X# of obscure clashes with user-ids. Explicit aliases of the form
- X# gradnews: gradnews@localnews
- X# should be used for those (such names are not a good idea to start with).
- X# If such aliases are used, add a line in hosts.transports that reads
- X# localnews usenet!
- X# This tells the router that mail to fake host localnews is to be sent to the
- X# local host (there is nothing after the !) on channel usenet.
- X
- X# this version forwards the article via mail to a server that will trust
- X# the return address.
- Xserver="feednews@news-server.csri.toronto.edu"
- X
- Xcase x$DISTRIBUTE in
- Xx) org="`cat /local/share/news/organi?ation`"
- X [ "$org" ] || org = "Department of Computer Science, University of Toronto"
- X orgflag=1
- X ;;
- X*) orgflag=0
- X ;;
- Xesac
- Xfrom=/tmp/from$$
- X
- Xfor i in $@
- Xdo
- X groups="${groups+$groups,}$i"
- Xdone
- X
- Xawk "BEGIN { subject = 0; body = 0; skipping = 0 ;
- X newsgroups = 0; distribution = 0;
- X organization = $orgflag;
- X print \"To: $server\" }
- Xbody == 1 { print; next }
- X/^$|^[ ][ \\t]*$/ { if (!body) {
- X np = split(path,parts,\"!\");
- X if (!organization && np == 1)
- X print \"Organization: $org\";
- X if (!newsgroups) print \"Newsgroups: $groups\";
- X if (!subject) print \"Subject: (none)\";
- X }
- X print; body = 1; next
- X }
- X/^To:|^X-To:|^Cc:|^Apparently-To:/ { skipping=1 ; next }
- X/^Newsgroups:/ { newsgroups = 1; skipping = 0; printf(\"%s\",\$0);
- X if (\"$groups\" != \"\")
- X printf(\",%s\\n\",\"$groups\");
- X else printf(\"\\n\");
- X next }
- X/^Distribution:/ { distribution = 1; skipping = 0; print; next }
- X/^Subject:/ { subject = 1; skipping = 0; print; next }
- X/^From |^Return-Path:/ { print \$2 > from ; path = \$2 ; skipping = 1; next }
- X/^[ ]/ { if (skipping) next }
- X/^[A-Za-z-]*:[ \\t]*$/ { if (!body) next }
- X { print }
- X" from="$from" - >/tmp/bug$$
- X
- Xif [ -s $from ]; then
- X /usr/lib/sendmail -f"`cat $from`" </tmp/bug$$
- Xfi
- Xrm $from /tmp/bug$$
- Xexit 0
- !
- echo 'contrib/nntpmail/mailing_lists/README':
- sed 's/^X//' >'contrib/nntpmail/mailing_lists/README' <<'!'
- XMANAGING AND REDISTRIBUTING MAILING LISTS
- X
- XThe tools described below allow you to set up a mailing list that is
- X- archived in a single file if you wish
- X- archived in one file per volume/issue if you wish
- X- gatewayed to a newsgroup (bi-directionally if you wish)
- X- well-behaved (the bounces go back to the owner, not to the whole list)
- X- protected from unauthorized perusal if you wish.
- X
- XThis requires something like the following aliases to be set-up.
- X
- X example: "|/local/lib/mail/bin/moderate example-owner example-people",
- X "|/local/lib/mail/bin/distribute -a example -n list.example"
- X example-request: lamy
- X example-owner: lamy
- X example-people: ":include:/local/share/mail/lists/example"
- X
- XFor bi-directional gatewaying you need to edit the sys file on the news
- Xserver:
- X
- X list.example:list.example/all::/news/bin/mailgateway example@ai.toronto.edu
- X
- XThe tools used are as follows:
- X
- Xa) redistributing a mailing list
- X
- Xmoderate: used for setting up mail aliases so that bounces don't pester
- X the whole membership. Typically the members of the list will
- X be another alias that invokes "distribute" (below) so that
- X the contents get archived or/and fed to newsgroups.
- X
- Xb) gatewaying mailing lists to newsgroups, archival
- X
- Xdistribute: takes a message, forwards it to mail recipients, gateways
- X into newsgroups, and archives the articles either one article
- X per file or mailbox style.
- X
- Xappendfile: setuid append program; required so that sensitive lists can
- X be protected.
- X
- X
- Xc) gatewaying of newsgroups into mailing lists (bidirectionally as well).
- X
- Xmailgateway: Used on the news server, and invoked from the sys file, this
- X script allows notification of people who can't/won't read news.
- X Messages posted to a newsgroup are fed to a mailing list, except
- X if the message appears to have come from the mailing list in the
- X first place. This is detected by looking for the Approved:
- X header "distribute" tacks on. News control messages are
- X weeded out.
- !
- echo 'contrib/nntpmail/mailing_lists/appendfile/Makefile':
- sed 's/^X//' >'contrib/nntpmail/mailing_lists/appendfile/Makefile' <<'!'
- XNAME=appendfile
- XDESTDIR=/ai/lib/mail/bin
- XMANEXT=1
- XMANDIR=/ai/man/man$(MANEXT)
- XCFLAGS=-O
- X
- Xall: $(NAME)
- X$(NAME): $(NAME).c
- X cc $(CFLAGS) $(NAME).c -o $(NAME)
- X
- Xinstall: all
- X install -s -m 755 $(NAME) $(DESTDIR)
- X# install -c -m a=r $(NAME).man $(MANDIR)/$(NAME).$(MANEXT)
- X
- Xclean:
- X rm -f *.o $(NAME) \#* *~
- !
- echo 'contrib/nntpmail/mailing_lists/appendfile/appendfile.c':
- sed 's/^X//' >'contrib/nntpmail/mailing_lists/appendfile/appendfile.c' <<'!'
- X#define BUFSIZ 1024
- X#include <sys/file.h>
- X
- Xmain(argc,argv)
- Xint argc;
- Xchar **argv;
- X{
- X char *ofile, buf[BUFSIZ];
- X int fd, n, p, neednl;
- X
- X argc--, argv++;
- X neednl = 0;
- X p = 1;
- X if (**argv == '-') {
- X if ((fd = open(argv[0]+1,O_WRONLY|O_APPEND|O_CREAT,0644)) < 0
- X || dup2(fd, 1) < 0) {
- X perror(argv[0]+1);
- X exit(1);
- X }
- X argc--, argv++;
- X }
- X while (argc--) {
- X if ((fd = open(*argv, 0)) < 0) {
- X perror(*argv++);
- X continue;
- X }
- X argv++;
- X if (neednl)
- X write(1, "\n", 1);
- X while ((n = read(fd, buf, BUFSIZ)) > 0) {
- X write(1, buf, n);
- X if (n == 1)
- X neednl = !(buf[0] == '\n' && buf[p-1] == '\n');
- X else
- X neednl = !(buf[n-1] == '\n' && buf[n-2]=='\n');
- X p = n;
- X }
- X close(fd);
- X }
- X if (neednl)
- X write(1, "\n", 1);
- X exit(0);
- X}
- !
- echo done
-
-
-